

#include <world.h>
#include <vector.h>
#include <camera.h>
#include <transform.h>

#include <math.h>
#include <string.h>
#include <stdlib.h>

vm_world *vm_make_empty_world(){

  vm_world *world = (vm_world *) malloc(sizeof(vm_world));
  return memset(world, 0, sizeof(vm_world));

}

void vm_free_world(vm_world *world){

  free((void *) world);

}


void vm_pregenerate(vm_world *world, vm_camera *cam){

  world->cam = cam;

  double ang_x = vm_angle(cam->look, UNIT_X);
  double ang_y = vm_angle(cam->look, UNIT_Y);
  double ang_z = vm_angle(cam->look, UNIT_Z);

#ifdef _DEBUG
  printf("[vm_pregenerate] ang_x: %f ang_y: %f ang_z: %f\n", 
	 ang_x, ang_y, ang_z);
#endif

  if (ang_x < .005){ // Screen space == cam space
    world->screen_space_basis[0] = UNIT_X;
    world->screen_space_basis[1] = UNIT_Y;
    world->screen_space_basis[2] = UNIT_Z; 
  } else if (ang_y < .005){
    world->screen_space_basis[0] = UNIT_Y;
    world->screen_space_basis[1] = UNIT_X;
    world->screen_space_basis[2] = UNIT_Z;
  } else if (ang_z < .005){ // Cam direction is parallel to Z axis.
    world->screen_space_basis[0] = UNIT_Z;
    world->screen_space_basis[1] = UNIT_Y;
    world->screen_space_basis[2] = UNIT_X;
  } else {
    vm_vector tmp[3];
    tmp[0] = cam->look;
    tmp[1] = UNIT_Y;
    tmp[2] = UNIT_Z;
    vm_vector *orth_tmp = vm_gram_schmidt_orth(tmp, 3);
    int i = 0;
    for ( ; i < 3; i++){
      world->screen_space_basis[i] = orth_tmp[i];
    }
    free((void *)orth_tmp);
  }

  world->space_trans = vm_make_space_trans_mtx(world->screen_space_basis);

  double tmp;
  vm_dot(world->cam->look, world->cam->location, &tmp);
  vm_vector loc_look;
  vm_add(world->cam->look, world->cam->location, &loc_look);
  tmp += vm_magnitude(loc_look);
  //tmp *= -1;
  world->t_num = tmp;

  vm_dot(world->cam->look, world->cam->location, &world->t_den);

}

void vm_print_world_data(vm_world *world){

  printf("World Data:\n");
  printf("  Camera orientation:\n    ");
  vm_println(world->cam->look);
  printf("  Camera location:\n    ");
  vm_println(world->cam->location);
  printf("  Camera screen size: %d:%d\n", 
	 world->cam->x_len, world->cam->y_len);
  printf("  Screen Space Basis vectors:\n");
  int i = 0;
  for ( ; i < 3; i++){
    printf("    "); vm_println(world->screen_space_basis[i]);
  }
  printf("  Space Trans Matrix:\n");
  vm_print_matrix(world->space_trans, "    ");
  printf("  t_num: %f\n", world->t_num);
  printf("  t_den: %f\n", world->t_den);

}
